package com.mdd.admin.controller;

import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.internal.util.AlipaySignature;
import com.mdd.admin.service.auth.AlipayAuthOrderFreezeService;
import com.mdd.admin.service.order.IOrderInfoService;
import com.mdd.admin.service.sign.AlipaySignUserAgreementRecordService;
import com.mdd.common.aop.NotLogin;
import com.mdd.common.config.AlipayConfiguration;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.entity.agreement.AlipayAuthOrderFreeze;
import com.mdd.common.entity.agreement.AlipaySignUserAgreementRecord;
import com.mdd.common.enums.auth.FundAuthFreezeStatus;
import com.mdd.common.enums.auth.SignResultEnum;
import com.mdd.common.enums.auth.TradeStatusEnum;
import com.mdd.common.enums.notify.NotifyTypeEnums;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * {@code @Description}
 * @Author 幻速
 * {@code @Date} 2023/11/6 15:57
 **/
@Slf4j
@RestController
@RequestMapping("api/notify")
@Api(tags = "主页数据管理")
public class NotifyMsgController {
    @Resource
    AlipayAuthOrderFreezeService alipayAuthOrderFreezeService;
    @Resource
    AlipaySignUserAgreementRecordService alipaySignUserAgreementRecordService;
    @Resource
    IOrderInfoService orderInfoService;

    @NotLogin
    @RequestMapping("/callback.htm")
    @ApiOperation(value = "预授权签约全生命周期支付宝通知")
    public String alipayFundAuthCallback(HttpServletRequest httpServletRequest) throws AlipayApiException {
        log.error("回调url：{}",httpServletRequest.getRequestURL());
        Map<String, String> params = convertRequestParamsToMap(httpServletRequest); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
        log.error("回调参数：{}", paramsJson);
        String notifyType = params.get("notify_type");
        String outOrderNo = params.get("out_order_no");
        String authNo = params.get("auth_no");
        log.info("支付宝回调，{}", paramsJson);
        // 调用SDK验证签名
        boolean signVerified = true;
//            signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(),
//                    alipayConfig.getCharset(), alipayConfig.getSignType());
        if (signVerified) {
            log.info("支付宝回调签 名认证成功");
            // 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success，校验失败返回failure
            // 另起线程处理业务
            // 如果签名验证正确，立即返回success，后续业务另起线程单独处理
            // 业务处理失败，可查看日志进行补偿，跟支付宝已经没多大关系。
            //fund_auth_freeze.init 资金预授权订单创建
            if (NotifyTypeEnums.FUND_AUTH_FREEZE_INIT.getCode().equals(notifyType)) {
                AlipayAuthOrderFreeze authInfo = alipayAuthOrderFreezeService.getAuthInfo(outOrderNo);
                //资金预授权订单创建
                authInfo.setStatus(FundAuthFreezeStatus.FUND_AUTH_FREEZE_INIT.getCode());
                alipayAuthOrderFreezeService.updateById(authInfo);
            } else if (NotifyTypeEnums.FUND_AUTH_FREEZE.getCode().equals(notifyType)) {
                AlipayAuthOrderFreeze authInfo = alipayAuthOrderFreezeService.getAuthInfo(outOrderNo);
                //资金预授权冻结成功/到达超时解冻时间触发自动解冻通知
                authInfo.setStatus(FundAuthFreezeStatus.FUND_AUTH_FREEZE.getCode());
                authInfo.setAuthNo(authNo);
                alipayAuthOrderFreezeService.updateById(authInfo);

            } else if (NotifyTypeEnums.FUND_AUTH_FREEZE_CLOSED.getCode().equals(notifyType)) {
                AlipayAuthOrderFreeze authInfo = alipayAuthOrderFreezeService.getAuthInfo(outOrderNo);
                //资金预授权订单关闭
                authInfo.setStatus(FundAuthFreezeStatus.FUND_AUTH_FREEZE_CLOSED.getCode());
                alipayAuthOrderFreezeService.updateById(authInfo);
            } else if (NotifyTypeEnums.FUND_AUTH_UNFREEZE.getCode().equals(notifyType)) {
                AlipayAuthOrderFreeze authInfo = alipayAuthOrderFreezeService.getAuthInfo(outOrderNo);
                //资金授权订单解冻
                authInfo.setStatus(FundAuthFreezeStatus.FUND_AUTH_UNFREEZE.getCode());
                alipayAuthOrderFreezeService.updateById(authInfo);
            } else if (NotifyTypeEnums.FUND_AUTH_OPERATION_CANCEL.getCode().equals(notifyType)) {
                AlipayAuthOrderFreeze authInfo = alipayAuthOrderFreezeService.getAuthInfo(outOrderNo);
                //资金预授权明细撤销
                authInfo.setStatus(FundAuthFreezeStatus.FUND_AUTH_OPERATION_CANCEL.getCode());
                authInfo.setAuthNo(authNo);
                alipayAuthOrderFreezeService.updateById(authInfo);
            }

            else if (NotifyTypeEnums.DUT_USER_SIGN.getCode().equals(notifyType)) {
                String agreementNo = params.get("agreement_no");
                String alipayUserId = params.get("alipay_user_id");
                String status = params.get("status");
                if(SignResultEnum.NORMAL.getCode().equals(status)) {

                    AlipaySignUserAgreementRecord alipaySignUserAgreementRecord = alipaySignUserAgreementRecordService.updateRecordByAlipayUserId(alipayUserId,agreementNo);
                    //代扣签约回调
                    alipaySignUserAgreementRecordService.finalSign(alipaySignUserAgreementRecord);
                }
            }
            else if (NotifyTypeEnums.DUT_USER_UNSIGN.getCode().equals(notifyType)) {
                String agreementNo = params.get("agreement_no");
                String status = params.get("status");
                if(SignResultEnum.UN_SIGN.getCode().equals(status)) {
                    AlipaySignUserAgreementRecord alipaySignUserAgreementRecord = alipaySignUserAgreementRecordService.cancelRecordByAlipayUserId(agreementNo);
                }else     if(SignResultEnum.APPLY_UNSIGN.getCode().equals(status)){
                    AlipaySignUserAgreementRecord alipaySignUserAgreementRecord = alipaySignUserAgreementRecordService.applyCancelRecordByAlipayUserId(agreementNo);

                }
            }
            //支付状态同步
            else if (NotifyTypeEnums.TRADE_STATUS_SYNC.getCode().equals(notifyType)) {
                String orderNo = params.get("out_trade_no");
                String tradeStatus = params.get("trade_status");
                String tradeNo = params.get("trade_no");
                if(TradeStatusEnum.TRADE_SUCCESS.getCode().equals(tradeStatus)) {
                    //交易成功 更改状态为已支付
                    orderInfoService.tradeSuccess(orderNo,tradeNo);
                }
            }
            else{
                return "failed";
            }
            return "success";
        } else {
            log.info("支付宝回调签名认证失败，signVerified=false, paramsJson:{}", paramsJson);
            return "modify_type";
        }
    }

    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<>();
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;
            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.substring(1));
            } else {
                retMap.put(name, "");
            }
        }
        return retMap;
    }

}
